﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using Telerik.WinControls;
using Pakxel.Data;
using Telerik.WinControls.UI;
using Pakxel.Framework;
using System.Data.Common;
using Telerik.WinControls.Data;

namespace Pakxel.SmartLogistic.Admon
{
    public partial class CxPWorkBench : Telerik.WinControls.UI.RadForm
    {
        private delegate bool RuleManager(string CString);
        private Pakxel.Framework.Rules ruleToCheck;
        private RuleManager IsNumeric;
        private MEDataDataContext DataContext;
        private UIHelper uiHelper;
        private T026 currRecord;
        private bool DeletingRow = false;
        public CxPWorkBench()
        {
            InitializeComponent();
        }

        private void SetupPagosGridView()
        {
            PagosGridView.AllowEditRow = false;
            PagosGridView.AutoGenerateColumns = false;

            GridViewDateTimeColumn colT030Fecha = new GridViewDateTimeColumn("T030Fecha", "T030Fecha");
            colT030Fecha.HeaderText = "Fecha";
            colT030Fecha.FormatInfo = new System.Globalization.CultureInfo("es-MX");
            colT030Fecha.FormatString = "{0:dd/MM/yyyy}";
            colT030Fecha.Width = 400;

            GridViewDecimalColumn colT030Anticipo = new GridViewDecimalColumn("T030Anticipo", "T030Anticipo");
            colT030Anticipo.HeaderText = "Monto";
            colT030Anticipo.FormatInfo = new System.Globalization.CultureInfo("es-MX");
            colT030Anticipo.FormatString = "{0:C}";
            colT030Anticipo.Width = 400;

            try
            {
                PagosGridView.Columns.Add(colT030Fecha);
                PagosGridView.Columns.Add(colT030Anticipo);
                foreach (GridViewDataColumn col in this.PagosGridView.Columns)
                {
                    col.BestFit();
                }
            }
            catch (SystemException se)
            {
                MainApp.WriteExceptionToLog(se);
            }
        }

        void SetUpEntidadesComboBox()
        {
            CatT011Entity.AutoFilter = true;
            // Obtener Combobox interno
            RadMultiColumnComboBoxElement Combo = CatT011Entity.MultiColumnComboBoxElement;
            CatT011Entity.AutoSizeDropDownToBestFit = true;
            Combo.EditorControl.MasterTemplate.AutoGenerateColumns = false;

            // Agregar Columnas
            GridViewTextBoxColumn column = new GridViewTextBoxColumn("T011Entity") { HeaderText = "Id Entidad" };
            Combo.Columns.Add(column);
            column = new GridViewTextBoxColumn("T011Nombre") { HeaderText = "Nombre(s)" };
            Combo.Columns.Add(column);
            column = new GridViewTextBoxColumn("T011RFC") { HeaderText = "RFC" };
            Combo.Columns.Add(column);
            // Obtener datos

            /// TODO : Solo los proveedores
            CatT011Entity.DataSource = (from E in DataContext.T011s select new { T011Entity = E.T011Entity, T011Nombre = E.T011Nombre, T011RFC = E.T011RFC });

            // Definir Campo de Busqueda y campo de seleccion
            CatT011Entity.DisplayMember = "T011Nombre";
            CatT011Entity.ValueMember = "T011Entity";

            // Definir Filtro de busqueda
            Combo.EditorControl.FilterDescriptors.Add(new FilterDescriptor(CatT011Entity.DisplayMember, FilterOperator.StartsWith, string.Empty));
            CatT011Entity.MultiColumnComboBoxElement.AutoCompleteMode = AutoCompleteMode.None;
            CatT011Entity.DropDownStyle = RadDropDownStyle.DropDown;
            //uiHelper.SetComboBoxFilter(ref CatT011Entity, "T011Entity", 1);
        }

        private void UpdateGraph()
        {
           try
           {
              cxpGraph.Series[0].Points.Clear();
              decimal? Facturado = DataContext.T026s.Sum(F => F.T026Importe);
              /// TODO : Corregir
              decimal? Anticipos = (decimal?)DataContext.T030s.Sum(A => A.T030Anticipo) ?? 0.0m;
              decimal? Vencido = 0.0m;
              DataContext.GetImporteVencidoCxP(ref Vencido);
              cxpGraph.Series[0].Points.Add(new DevExpress.XtraCharts.SeriesPoint("Pendiente", Facturado-Anticipos));
              cxpGraph.Series[0].Points.Add(new DevExpress.XtraCharts.SeriesPoint("Al Corriente", Anticipos));
              cxpGraph.Series[0].Points.Add(new DevExpress.XtraCharts.SeriesPoint("Vencido", Vencido));
           }
           catch (SystemException se)
           {
              MainApp.WriteExceptionToLog(se);
           }
        }

        private void SetupWorkBench()
        {
            uiHelper.ClearControls(gpoCxP.Controls);
            SetUpEntidadesComboBox();
            SetupPagosGridView();
            UpdateGraph();     
        }

        private void CxPWorkBench_Load(object sender, EventArgs e)
        {
            WorkBenchFilter.TextBox.BackColor = Color.LightYellow;
            DataContext = new MEDataDataContext(WorkBench.ConnectionString);
            FilterSelector.SelectedIndex = 0;
            ruleToCheck = new Rules();
            IsNumeric += new RuleManager(ruleToCheck.IsNumeric);
            uiHelper = new UIHelper();
            SetupWorkBench();
        }

        private void UpdateSaldo()
        {
            if (currRecord != null)
            {
                var Anticipos = (from P in DataContext.T030s
                                 where P.T026Id.Equals(currRecord.T026Id)
                                 select P);
                if (Anticipos != null)
                {
                    var Suma = Anticipos.Sum(s => (decimal?)s.T030Anticipo) ?? 0m;
                    SaldoFactura.Text = string.Format("{0:C}", currRecord.T026Importe - Suma);
                }
                else
                {
                    SaldoFactura.Text = string.Format("{0:C}", 0);
                }
            }
        }

        private void UpdateSaldoGridView()
        {
            if (currRecord != null)
            {
                decimal Saldo = 0;
                foreach (Telerik.WinControls.UI.GridViewRowInfo Row in PagosGridView.Rows)
                {
                    Saldo += Convert.ToDecimal(Row.Cells["T030Anticipo"].Value);
                }
                SaldoFactura.Text = string.Format("{0:C}", currRecord.T026Importe - Saldo);
            }
        }

        private void ShowCxPRecord(T026 T026Record)
        {
            if (T026Record != null)
            {
                CatT011Entity.Text = T026Record.T011Entity.ToString();
                T026FechaIngreso.DateTime = T026Record.T026FechaIngreso;
                T026NoFactura.Text = T026Record.T026NoFactura;
                T026Importe.Text = string.Format("{0:C}", T026Record.T026Importe);
                UpdateSaldo();
                /// TODO : Hack para aplicar filtro con el mismo indice que el elemento seleccionado
                var Indice = CatT011Entity.SelectedIndex;
                uiHelper.SetComboBoxFilter(ref CatT011Entity, "T011Entity", T026Record.T011Entity);
                CatT011Entity.SelectedIndex = -1;
                CatT011Entity.SelectedIndex = Indice;
                PagosGridView.DataSource = T026Record.T030s;
                foreach (GridViewDataColumn col in this.PagosGridView.Columns)
                {
                    col.BestFit();
                }
            }
            else
            {
                uiHelper.ClearControls(this.Controls);
                statusMsg.Text = string.Empty;
            }
        }

        private void WorkBenchFilter_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                var T011Entity = (int)CatT011Entity.EditorControl.Rows[CatT011Entity.SelectedIndex].Cells["T011Entity"].Value;
                currRecord = (from F in DataContext.T026s
                              where F.T011.T011Entity.Equals(T011Entity)
                                  && F.T026NoFactura.Equals(WorkBenchFilter.Text)
                              select F).SingleOrDefault();
                if (currRecord != null)
                {
                    ShowCxPRecord(currRecord);
                    statusMsg.Text = string.Empty;
                }
                else
                {
                    uiHelper.ClearControls(gpoCxP.Controls);
                    uiHelper.ClearComboBoxFilter(ref CatT011Entity);
                    PagosGridView.DataSource = null;
                    statusMsg.Text = string.Format("No existe la factura {0}", WorkBenchFilter.Text);
                }
            }
        }

        private void tsbSave_Click(object sender, EventArgs e)
        {
            /// TODO : Validar Campos 
            if (currRecord == null)
            {
                if (DataContext.Connection.State != ConnectionState.Closed)
                {
                    DataContext.Connection.Close();
                    DataContext.Connection.Open();
                }
                else
                    DataContext.Connection.Open();
                /// TODO : Es necesaria la transaccion ? , ... no se hace uso de folios
                using (DbTransaction transaction = DataContext.Connection.BeginTransaction(IsolationLevel.Serializable))
                {
                    DataContext.Transaction = transaction;
                    try
                    {
                        currRecord = new T026();
                        currRecord.T011Entity = (int)CatT011Entity.EditorControl.Rows[CatT011Entity.SelectedIndex].Cells["T011Entity"].Value;
                        currRecord.T026FechaIngreso = T026FechaIngreso.DateTime;
                        currRecord.T026NoFactura = T026NoFactura.Text;
                        if (Convert.ToDecimal(T026Importe.Text) > 0)
                        {
                            currRecord.T026Importe = Convert.ToDecimal(T026Importe.Text);
                        }
                        UpdateSaldo();
                        UpdateSaldoGridView();
                        DataContext.T026s.InsertOnSubmit(currRecord);
                        DataContext.SubmitChanges();
                        transaction.Commit();
                        T026Importe.Text = string.Format("{0:C}", currRecord.T026Importe);
                        UpdateGraph();
                    }
                    catch (System.Data.Linq.ChangeConflictException cce)
                    {
                        MessageBox.Show("Error");
                        MainApp.WriteExceptionToLog(cce);
                        transaction.Rollback();
                    }
                    catch (SystemException se)
                    {
                        MainApp.WriteExceptionToLog(se);
                        transaction.Rollback();
                    }
                    finally
                    {
                        DataContext.Connection.Close();
                    }
                }
            }
            // Se esta editando el registro actual
            else
            {
                ///TODO : Si ya esta saldada la factura solicitar codigo de supervisor para hacerle cambios
                try
                {
                    var Indice = CatT011Entity.SelectedIndex;
                    currRecord.T011Entity = (int)CatT011Entity.EditorControl.Rows[CatT011Entity.SelectedIndex].Cells["T011Entity"].Value;
                    currRecord.T026FechaIngreso = T026FechaIngreso.DateTime;
                    currRecord.T026NoFactura = T026NoFactura.Text;
                    T026Importe.Text = T026Importe.Text.Replace("$", "");
                    T026Importe.Text = T026Importe.Text.Replace(",", "");
                    T026Importe.Text = T026Importe.Text.Trim();
                    /// TODO : Validar si se permite el cambio de importe por uno menor cuando ya tiene anticipos
                    /// , ej. que pasa con los anticipos ?
                    currRecord.T026Importe = Convert.ToDecimal(T026Importe.Text);
                    DataContext.SubmitChanges();
                    UpdateSaldo();
                    UpdateSaldoGridView();
                    T026Importe.Text = string.Format("{0:C}", currRecord.T026Importe);
                    UpdateGraph();
                }
                catch (System.Data.Linq.ChangeConflictException cce)
                {
                    MessageBox.Show("Error");
                    MainApp.WriteExceptionToLog(cce);
                }
                catch (SystemException se)
                {
                    MainApp.WriteExceptionToLog(se);
                }
                finally
                {
                    DataContext.Connection.Close();
                }
            }
        }

        private void cxpGraph_DoubleClick(object sender, EventArgs e)
        {
            //MessageBox.Show("CxP Detalle");
            DetalleCxPWorkBench detalleCxP = new DetalleCxPWorkBench() { MdiParent=MainApp.Wb};
            detalleCxP.Show();
        }

        private void tsbNvo_Click(object sender, EventArgs e)
        {
            uiHelper.EnableControls(gpoPagos, true, true);
            WorkBenchFilter.Text = string.Empty;
            uiHelper.ClearComboBoxFilter(ref CatT011Entity);
            uiHelper.ClearControls(this.Controls);
            statusMsg.Text = string.Empty;
            currRecord = null;
        }

        private void tsbEdit_Click(object sender, EventArgs e)
        {
            uiHelper.EnableControls(this.gpoPagos, true, false);
            uiHelper.ClearComboBoxFilter(ref CatT011Entity);
            cxpGraph.Series[0].Points.Clear();
        }

        private void PagosGridView_UserDeletedRow(object sender, GridViewRowEventArgs e)
        {
            DeletingRow = false;
            UpdateSaldoGridView();
        }

        private void PagosGridView_CellValidating(object sender, CellValidatingEventArgs e)
        {
            if (!DeletingRow && currRecord!=null)
            {
                if (e.Column.Name.Equals("T030Anticipo") && e.OldValue != e.Value)
                {
                    var Anticipo = (decimal)e.Value;
                    var Saldo = 0.0m;
                    if (Anticipo <= 0)
                    {
                        e.Cancel = true;
                    }
                    else
                    {
                        var Anticipos = (from P in DataContext.T030s
                                         where P.T026Id.Equals(currRecord.T026Id)
                                         select P);
                        if (Anticipos != null)
                        {
                            var Suma = Anticipos.Sum(s => (decimal?)s.T030Anticipo) ?? 0m;
                            if (Suma > 0)
                            {
                               Saldo = Suma + Anticipo;
                               if (Saldo > currRecord.T026Importe)
                               {
                                  e.Cancel = true;
                               }
                            }
                            else if(Anticipo > currRecord.T026Importe)
                            {
                               e.Cancel = true;
                            }
                        }
                    }
                }
            }
        }

        private void PagosGridView_UserDeletingRow(object sender, GridViewRowCancelEventArgs e)
        {
            DeletingRow = true;
            UpdateSaldoGridView();
        }

        private void PagosGridView_CellValidated(object sender, CellValidatedEventArgs e)
        {
           UpdateSaldo();
           UpdateSaldoGridView();
           UpdateGraph();
        }
    }
}
